from typing import Optional, List, Dict
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy_crud_plus import CRUDPlus

from modules.system.models.dict import DictType
from modules.system.models.dict_item import Dictionary
from modules.system.schemas.dict_schemas import DictTypeCreate, DictTypeUpdate


class DictTypeRepository(CRUDPlus[DictType]):
    async def get_by_id(self, db: AsyncSession, pk: int) -> Optional[DictType]:
        return await self.select_model_by_column(db, id=pk, status=1)

    async def get_by_code(self, db: AsyncSession, type_code: str) -> Optional[DictType]:
        return await self.select_model_by_column(db, type_code=type_code, status=1)

    async def get_by_name(self, db: AsyncSession, type_name: str) -> Optional[DictType]:
        return await self.select_model_by_column(db, type_name=type_name, status=1)

    async def create(self, db: AsyncSession, data: DictTypeCreate) -> DictType:
        return await self.create_model(db, data)

    async def update(self, db: AsyncSession, pk: int, data: DictTypeUpdate) -> Optional[DictType]:
        await self.update_model(db, pk, data)
        return await self.select_model(db, pk)

    async def delete(self, db: AsyncSession, pk: int) -> bool:
        return await self.delete_model(db, pk)

    async def get_items_grouped_by_types(
        self, db: AsyncSession, type_codes: Optional[List[str]] = None
    ) -> Dict[str, List[Dictionary]]:
        """批量获取字典项并按类型分组（供前端缓存）。"""
        q = select(Dictionary)
        if type_codes:
            q = q.where(Dictionary.dict_type.in_(type_codes))

        q = q.order_by(
            Dictionary.dict_type.asc(),
            Dictionary.sort_order.asc(),
            Dictionary.id.desc(),
        )

        res = await db.execute(q)
        items = res.scalars().all()

        grouped: Dict[str, List[Dictionary]] = {}
        for it in items:
            grouped.setdefault(it.dict_type, []).append(it)

        return grouped


dict_type_dao = DictTypeRepository(DictType)